package com.iqiyi.pps.epg.web.timer;

import com.alibaba.fastjson.JSONObject;
import com.iqiyi.pps.epg.core.model.program.*;
import com.iqiyi.pps.epg.core.service.program.ProgramService;
import com.iqiyi.pps.epg.core.utils.ApiFeedUtil;
import com.iqiyi.pps.epg.core.utils.Constants;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by karkarrotxu on 2015/7/24.
 */
public class AutoSendFeedTrigger {
    private static Logger logger = LoggerFactory.getLogger(AutoSendFeedTrigger.class);
    private static Map<Long, ProgramFeedData> checkMap = new HashMap<Long, ProgramFeedData>(512);
    @Autowired
    private ProgramService programService;
    private long loopMin = 0;
    private long loopMax = 0;
    public static final long BUFF_TIME = 180000L;

    public AutoSendFeedTrigger() {

    }

    public void task() {
        try{
            doCheckSendFeed();
        }catch (Exception e){
            logger.error("doCheckSendFeed",e);
        }

        try{
            doCheckClearFeed();
        }catch (Exception e){
            logger.error("doCheckClearFeed",e);
        }

    }

    public void doCheckSendFeed() {
        logger.info("doCheckSendFeed start");
        long checkStartTime = System.currentTimeMillis();
        loopMin = checkStartTime;
        loopMax = checkStartTime + BUFF_TIME;
        List<ProgramData> list = programService.checkFeedListQuery(loopMin, loopMax);
        if (list != null) {
            for (ProgramData p : list) {
                ProgramFeedData checkData = null;
                if (p.getDeleteFlag() == 1) {
                    if (checkMap.containsKey(p.getId())) {
                        checkMap.remove(p.getId());
                        logger.info("[remove program][pid={}][qipuId={}]", p.getId(), p.getQipuId());
                    }
                    continue;
                }
                if (!checkMap.containsKey(p.getId())) {
                    checkData = new ProgramFeedData();
                    checkData.setId(p.getId());
                    checkData.setFatherId(p.getFatherId());
                    checkData.initByTime(p.getStartPlayTime().getTime());
                    checkMap.put(checkData.getId(), checkData);
                } else {
                    checkData = checkMap.get(p.getId());
                    if (checkData.getStartTime() != p.getStartPlayTime().getTime()) {
                        checkData.initByTime(p.getStartPlayTime().getTime());
                    }
                }
            }
        }

        List<ProgramFeedData> checkList = new ArrayList<ProgramFeedData>(checkMap.values());
        List<Long> removeList = new ArrayList<Long>();
        for (ProgramFeedData temp : checkList) {
            ProgramFeedData.STATUS status = temp.getCheckStatus(checkStartTime);
            switch (status) {
                case PHASE_OVER_CHECK:
                    temp.setLastExcuteTime(checkStartTime);
                    removeList.add(temp.getId());
                    break;
                case PHASE_CHECK_SECOND:
                    doSendFeed(temp);
                    temp.setLastExcuteTime(checkStartTime);
                    break;
                case IN_WAIT:
                    break;
            }
        }
        if (removeList.size() > 0) {
            logger.info("[CheckListTrigger][task]remove " + removeList.toString());
            for (Long removeId : removeList) {
                checkMap.remove(removeId);
            }
        }
        logger.info("doCheckSendFeed end");
    }

    public void doCheckClearFeed() {
        logger.info("doCheckClearFeed start");
        List<Criterion> criterions = new ArrayList<>();
        criterions.add(Restrictions.eq("status", 0));
        criterions.add(Restrictions.eq("offLine", 1));
        List<FeedData> datas = programService.findFeedData(criterions);
        String ret = null;
        ProgramData programData;
        List<Criterion> cList = new ArrayList<Criterion>();
        List<ProgramLog> logList = new ArrayList<>();
        List<FeedData> feedDataList = new ArrayList<FeedData>();
        for (FeedData temp : datas) {
            cList.clear();
            programData = programService.findProgramDataByQipuId(temp.getProgramQipuId());
            cList.add(Restrictions.eq("fatherId", programData.getId()));
            cList.add(Restrictions.eq("type", 7)); //关联直播节目类型;
            List<ProgramDataBase> list = programService.queryDataBaseByCriterion(cList, null);
            if (list.size() == 0) {
                ret = ApiFeedUtil.delFeed(temp.getProgramQipuId());
                logList.add(buildFeedLog(programData.getId(), Constants.LogType.PROGRAM_CLEAR_FEED.getIndex(), ret));
                JSONObject jsonObject = JSONObject.parseObject(ret);
                if(ret == null){
                    temp.setStatus(FeedData.STATUS_INTERRUPT);
                    feedDataList.add(temp);
                }else if ("A00000".equals(jsonObject.get("code"))) {
                    temp.setStatus(FeedData.STATUS_COMPLETE);
                    feedDataList.add(temp);
                }
            } else {
                temp.setStatus(FeedData.STATUS_INTERRUPT);
                feedDataList.add(temp);
            }
        }
        programService.batchUpdateFeedDataList(feedDataList);
        programService.saveProgramLogList(logList);
        logger.info("doCheckClearFeed end");
    }

    public boolean doSendFeed(ProgramFeedData programFeedData) {
        ProgramData p = programService.findProgramDataById(programFeedData.getId());
        if (p.getOaDocNo() != null && "ZB-TW-001".equalsIgnoreCase(p.getOaDocNo())) {
            logger.info("case ZB-TW-001 skip send:" + p.getQipuId());
            return true;
        }
        if (p.getTest() == 1) {
            logger.info("case testMode skip send:" + p.getQipuId());
            return true;
        }
        try {
            List<Criterion> cList = new ArrayList<Criterion>();
            cList.add(Restrictions.eq("fatherId", p.getId()));
            cList.add(Restrictions.eq("type", 401)); //圈子类型
            List<ProgramDataBase> list1 = programService.queryDataBaseByCriterion(cList, null);
            List<String> circleList = new ArrayList<String>();
            for (ProgramDataBase temp : list1) {
                circleList.add(temp.getKey() + "47"); // 圈子奇谱ID 后缀
            }
            // find uid data ;
            cList.clear();
            cList.add(Restrictions.eq("fatherId", p.getId()));
            cList.add(Restrictions.eq("type", 301));//用户uid 类型
            List<ProgramDataBase> list2 = programService.queryDataBaseByCriterion(cList, null);
            long uid = 0;
            if (list2.size() > 0) {
                uid = Long.valueOf(list2.get(0).getValue());
            }else{
                uid = ApiFeedUtil.DEFAULT_IQIYI_UID;
            }
            String retValue = ApiFeedUtil.delFeed( p.getQipuId() );
            saveFeedLog(p.getId(), Constants.LogType.PROGRAM_CLEAR_FEED.getIndex(), retValue + "||params:" + p.getQipuId() +" (do clear before send)" );
            //A00000 操作成功，B00008 没有权限，B00005 参数错误,"B00003 内部异常"
            List<String> retValueList = ApiFeedUtil.addFeed(p.getQipuId(), circleList, uid);
            saveFeedLog(p.getId(), Constants.LogType.PROGRAM_ADD_FEED.getIndex(), retValueList + "||params:" + p.getQipuId() + "|" + uid+"|"+circleList);
            if (retValueList != null) {
                for (String temp : retValueList) {
                    JSONObject jsonObject = JSONObject.parseObject(temp);
                    if (jsonObject != null && "A00000".equals(jsonObject.get("code"))) {
                        List<Criterion> list = new ArrayList<>();
                        list.add(Restrictions.eq("programQipuId", p.getQipuId()));
                        list.add(Restrictions.eq("status", 0));
                        List<FeedData> feedDataList = programService.findFeedData(list);
                        if (feedDataList.size() == 0) {
                            FeedData feedData = new FeedData();
                            feedData.setProgramQipuId(p.getQipuId());
                            programService.addFeedData(feedData);
                        }
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("ERROR" + p.getQipuId(), e);
        }
        logger.info("doSendFeed fail:"+p.getQipuId());
        return false;
    }

    public void saveFeedLog(long programId, int logType, String descr) {
        ProgramLog log = new ProgramLog();
        log.setProgramId(programId);
        log.setType(logType);
        log.setDescription(descr);
        log.setUser(Constants.SYSTEM_USER_SIGN);
        programService.saveProgramLog(log);
    }

    public ProgramLog buildFeedLog(long programId, int logType, String descr) {
        ProgramLog log = new ProgramLog();
        log.setProgramId(programId);
        log.setType(logType);
        log.setDescription(descr);
        log.setUser(Constants.SYSTEM_USER_SIGN);
        return log;
    }

}

